#include <iostream>
#include <ratio>
#include <typeinfo>
#include <type_traits>

using namespace std;

template <size_t N>
constexpr size_t AddN = std::ratio_add<std::ratio<N>, std::ratio<1>>::num;

template <size_t N>
constexpr size_t DecN = std::ratio_subtract<std::ratio<N>, std::ratio<1>>::num;

template<size_t X, size_t N>
constexpr size_t PowN = std::ratio_multiply<std::ratio<X>, std::ratio<PowN<X, DecN<N>>>>::num;

template<size_t X>
constexpr size_t PowN<X, 0> = 1;

template<size_t X, size_t N, size_t R = 1>
constexpr size_t Sqrt = std::ratio_greater_v<std::ratio<PowN<R, N>>, std::ratio<X>> ? DecN<R> : Sqrt<X, N, AddN<R>>;

template<size_t X, size_t N>
constexpr size_t Sqrt<X, N, X> = X;
template<size_t N>
constexpr size_t Sqrt<2, N> = 1;
template<>
constexpr size_t Sqrt<2, 1> = 2;

int main()
{
	cout << "1   ^ 1/2\t" << Sqrt<1, 2> << endl;
	cout << "2   ^ 1/2\t" << Sqrt<2, 2> << endl;
	cout << "4   ^ 1/2\t" << Sqrt<4, 2> << endl;
	cout << "8   ^ 1/2\t" << Sqrt<8, 2> << endl;
	cout << "16  ^ 1/2\t" << Sqrt<16, 2> << endl;
	cout << "32  ^ 1/2\t" << Sqrt<32, 2> << endl;
	cout << "64  ^ 1/2\t" << Sqrt<64, 2> << endl;
	cout << "128 ^ 1/2\t" << Sqrt<128, 2> << endl;

	cout << "1   ^ 1/1\t" << Sqrt<1, 1> << endl;
	cout << "2   ^ 1/1\t" << Sqrt<2, 1> << endl;
	cout << "4   ^ 1/1\t" << Sqrt<4, 1> << endl;
	cout << "8   ^ 1/1\t" << Sqrt<8, 1> << endl;
	cout << "16  ^ 1/1\t" << Sqrt<16, 1> << endl;
	cout << "32  ^ 1/1\t" << Sqrt<32, 1> << endl;
	cout << "64  ^ 1/1\t" << Sqrt<64, 1> << endl;
	cout << "128 ^ 1/1\t" << Sqrt<128, 1> << endl;

	return 0;
}